﻿#region Copyright Notices
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
// 
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#endregion

using System;
using System.Collections;
using System.Collections.Generic;

namespace Yarr.YarrPad
{
    internal class CommandHistory : IEnumerable<string>
    {
        internal const int DefaultBufferSize = 20;

        private readonly List<string> buffer;
        private int currentPosition;
        private bool currentReturned;

        public CommandHistory() : this(DefaultBufferSize)
        {
        }

        public CommandHistory(int bufferSize)
        {
            if (bufferSize <= 0)
            {
                throw new ArgumentOutOfRangeException("bufferSize");
            }
            buffer = new List<string>(bufferSize);
        }

        private int FindIndex(string entry)
        {
            for (int i = 0; i < buffer.Count; i++)
            {
                if (entry.Equals(buffer[i], StringComparison.Ordinal))
                {
                    return i;
                }
            }
            return -1;
        }

        public void AddEntry(string entry)
        {
            int index = FindIndex(entry);
            currentReturned = false;
            if (index >= 0)
            {
                currentPosition = index;
                return;
            }

            if (buffer.Count == buffer.Capacity)
            {
                buffer.RemoveAt(0);
            }
            buffer.Add(entry);
            currentPosition = buffer.Count - 1;
        }

        public string PreviousEntry()
        {
            if ((buffer.Count == 0) || (currentPosition < 0))
            {
                return null;
            }
            if (!currentReturned)
            {
                currentReturned = true;
                return buffer[currentPosition];
            }
            currentPosition -= 1;
            if (currentPosition < 0)
            {
                currentPosition = 0;
            }
            return buffer[currentPosition];
        }

        public string NextEntry()
        {
            if ((buffer.Count == 0) || (currentPosition < 0))
            {
                return null;
            }
            if (currentPosition >= buffer.Count - 1)
            {
                return buffer[buffer.Count - 1];
            }
            currentReturned = true;
            currentPosition += 1;
            return buffer[currentPosition];
        }

        IEnumerator<string> IEnumerable<string>.GetEnumerator()
        {
            return buffer.GetEnumerator();
        }

        public IEnumerator GetEnumerator()
        {
            return buffer.GetEnumerator();
        }
    }
}